#include "widget.h"
#include "ui_widget.h"
#include <QTcpSocket>
#include <QMessageBox>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //设置窗口标题
    this->setWindowTitle("服务器");

    //1.创建Tcp Server
    tcpServer = new QTcpServer(this);

    //1.5 绑定信号槽
    connect(tcpServer,&QTcpServer::newConnection,this,&Widget::handleNewConnection);

    //2.bind and listen
    //当我们开始监听之后，就代表可以接受客户端的连接了，所以我们要在listen之前绑定新连接到来的信号槽
    bool ret = tcpServer->listen(QHostAddress::AnyIPv4,8080);
    if(!ret){
        //绑定失败的情况
        QMessageBox::critical(this,"bind error",tcpServer->errorString());
        exit(1);
    }

}

Widget::~Widget()
{
    delete ui;
}

QString process(const QString &request)
{
    //不进行实际的业务处理
    return request;
}

//新连接到来之后执行的处理
void Widget::handleNewConnection()
{
     //获取新连接
     QTcpSocket *socket = tcpServer->nextPendingConnection();

     //将日志显示在窗口上
     QString log = "[" + socket->peerAddress().toString() + ":" + QString::number(socket->peerPort()) + "]" + ": 已上线";
     ui->listWidget->addItem(log);

     //绑定可读事件信号槽
     connect(socket,&QTcpSocket::readyRead,this,[=](){
         //读取缓冲区中数据
         QString request = socket->readAll(); //会有粘包问题 ，但我们是echo server

         //对请求信息进行处理 （由于我们是echo 服务器，所以这里的业务逻辑不实现）
         QString response = process(request);

         //发送响应信息
         socket->write(response.toUtf8());

         //显示日志
         QString log = "[" + socket->peerAddress().toString() + ":" + QString::number(socket->peerPort()) + "]" +
                        "req: " + request + ", resp: " + response;
         ui->listWidget->addItem(log);

     });

     //绑定断开连接信号槽
     connect(socket,&QTcpSocket::disconnected,this,[=](){
         //显示日志
         QString log = "[" + socket->peerAddress().toString() + ":" + QString::number(socket->peerPort()) + "]" + ": 已下线";
         ui->listWidget->addItem(log);

         //删除对应的QTcpSocket 对象
         //暂时把socket对象标记为⽆效，会在下一个事件循环中delete掉这个对象
         socket->deleteLater();
     });
}

